package services

import (
	"errors"
	"time"

	"gorm.io/gorm"

	"chat-app/internal/app/models"
)

// ChatService 聊天服务接口
type ChatService interface {
	// 私聊相关
	SendPrivateMessage(senderID, recipientID uint, content string) (*models.Message, error)
	GetPrivateHistory(senderID, recipientID uint, page, pageSize int) ([]*models.Message, error)

	// 群聊相关
	CreateGroup(name string, creatorID uint) (*models.Group, error)
	AddGroupMember(groupID, userID, requesterID uint) error
	RemoveGroupMember(groupID, userID, requesterID uint) error
	SendGroupMessage(senderID, groupID uint, content string) (*models.Message, error)
	GetGroupHistory(groupID uint, page, pageSize int) ([]*models.Message, error)

	// 消息管理
	DeleteMessage(messageID, userID uint) error
	RecallMessage(messageID, userID uint) error
}

type chatService struct {
	db *gorm.DB
}

func NewChatService(db *gorm.DB) ChatService {
	return &chatService{db: db}
}

// SendPrivateMessage 发送私聊消息
func (s *chatService) SendPrivateMessage(senderID, recipientID uint, content string) (*models.Message, error) {
	if senderID == recipientID {
		return nil, errors.New("cannot send message to yourself")
	}

	// 检查发送者和接收者是否存在
	var sender, recipient models.User
	if err := s.db.First(&sender, senderID).Error; err != nil {
		return nil, errors.New("sender not found")
	}
	if err := s.db.First(&recipient, recipientID).Error; err != nil {
		return nil, errors.New("recipient not found")
	}

	// 创建消息
	message := models.Message{
		SenderID:    senderID,
		RecipientID: recipientID,
		Content:     content,
		MessageType: models.MessageTypePrivate,
		CreatedAt:   time.Now(),
	}

	if err := s.db.Create(&message).Error; err != nil {
		return nil, err
	}

	return &message, nil
}

// GetPrivateHistory 获取私聊历史
func (s *chatService) GetPrivateHistory(senderID, recipientID uint, page, pageSize int) ([]*models.Message, error) {
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}
	offset := (page - 1) * pageSize

	var messages []*models.Message
	err := s.db.Where("(sender_id = ? AND recipient_id = ?) OR (sender_id = ? AND recipient_id = ?)",
		senderID, recipientID, recipientID, senderID).
		Where("message_type = ?", models.MessageTypePrivate).
		Order("created_at DESC").
		Offset(offset).
		Limit(pageSize).
		Find(&messages).Error

	return messages, err
}

// CreateGroup 创建群组
func (s *chatService) CreateGroup(name string, creatorID uint) (*models.Group, error) {
	if name == "" {
		return nil, errors.New("group name cannot be empty")
	}

	group := models.Group{
		Name:      name,
		CreatorID: creatorID,
		CreatedAt: time.Now(),
	}

	if err := s.db.Create(&group).Error; err != nil {
		return nil, err
	}

	// 添加创建者为群成员
	if err := s.AddGroupMember(group.ID, creatorID, creatorID); err != nil {
		// 创建失败则回滚
		s.db.Delete(&group)
		return nil, err
	}

	return &group, nil
}

// AddGroupMember 添加群成员
func (s *chatService) AddGroupMember(groupID, userID, requesterID uint) error {
	// 检查群组是否存在
	var group models.Group
	if err := s.db.First(&group, groupID).Error; err != nil {
		return errors.New("group not found")
	}

	// 检查用户是否存在
	var user models.User
	if err := s.db.First(&user, userID).Error; err != nil {
		return errors.New("user not found")
	}

	// 只有群主可以添加成员
	if group.CreatorID != requesterID {
		return errors.New("only group creator can add members")
	}

	// 检查是否已是成员
	var existingMember models.GroupMember
	if err := s.db.Where("group_id = ? AND user_id = ?", groupID, userID).
		First(&existingMember).Error; err == nil {
		return errors.New("user is already in the group")
	}

	// 创建成员关系
	member := models.GroupMember{
		GroupID:  groupID,
		UserID:   userID,
		JoinedAt: time.Now(),
	}

	return s.db.Create(&member).Error
}

// RemoveGroupMember 移除群成员
func (s *chatService) RemoveGroupMember(groupID, userID, requesterID uint) error {
	// 检查群组是否存在
	var group models.Group
	if err := s.db.First(&group, groupID).Error; err != nil {
		return errors.New("group not found")
	}

	// 只有群主可以移除成员
	if group.CreatorID != requesterID {
		return errors.New("only group creator can remove members")
	}

	// 不能移除群主自己
	if userID == requesterID {
		return errors.New("group creator cannot remove themselves")
	}

	// 删除成员关系
	result := s.db.Where("group_id = ? AND user_id = ?", groupID, userID).
		Delete(&models.GroupMember{})

	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("user not in the group")
	}

	return nil
}

// SendGroupMessage 发送群聊消息
func (s *chatService) SendGroupMessage(senderID, groupID uint, content string) (*models.Message, error) {
	// 检查群组是否存在
	var group models.Group
	if err := s.db.First(&group, groupID).Error; err != nil {
		return nil, errors.New("group not found")
	}

	// 检查发送者是否是群成员
	var member models.GroupMember
	if err := s.db.Where("group_id = ? AND user_id = ?", groupID, senderID).
		First(&member).Error; err != nil {
		return nil, errors.New("sender is not a member of the group")
	}

	// 创建消息
	message := models.Message{
		SenderID:    senderID,
		GroupID:     groupID,
		Content:     content,
		MessageType: models.MessageTypeGroup,
		CreatedAt:   time.Now(),
	}

	if err := s.db.Create(&message).Error; err != nil {
		return nil, err
	}

	return &message, nil
}

// GetGroupHistory 获取群聊历史
func (s *chatService) GetGroupHistory(groupID uint, page, pageSize int) ([]*models.Message, error) {
	// 检查群组是否存在
	var group models.Group
	if err := s.db.First(&group, groupID).Error; err != nil {
		return nil, errors.New("group not found")
	}

	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}
	offset := (page - 1) * pageSize

	var messages []*models.Message
	err := s.db.Where("group_id = ? AND message_type = ?", groupID, models.MessageTypeGroup).
		Order("created_at DESC").
		Offset(offset).
		Limit(pageSize).
		Find(&messages).Error

	return messages, err
}

// DeleteMessage 删除消息
func (s *chatService) DeleteMessage(messageID, userID uint) error {
	var message models.Message
	if err := s.db.First(&message, messageID).Error; err != nil {
		return errors.New("message not found")
	}

	// 只有消息发送者可以删除消息
	if message.SenderID != userID {
		return errors.New("only message sender can delete the message")
	}

	return s.db.Delete(&message).Error
}

// RecallMessage 撤回消息
func (s *chatService) RecallMessage(messageID, userID uint) error {
	var message models.Message
	if err := s.db.First(&message, messageID).Error; err != nil {
		return errors.New("message not found")
	}

	// 只有消息发送者可以撤回消息
	if message.SenderID != userID {
		return errors.New("only message sender can recall the message")
	}

	// 超过5分钟不能撤回
	if time.Since(message.CreatedAt) > 5*time.Minute {
		return errors.New("message can only be recalled within 5 minutes")
	}

	// 标记消息为已撤回
	message.IsRecalled = true
	return s.db.Save(&message).Error
}
